package com.ocom.webapi.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ocom.common.constant.WebApiServiceUrl;
import com.ocom.common.entity.master.EntityWechatAppInfo;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.request.payconfig.restaurant.*;
import com.ocom.common.request.ugcapi.order.LoadRestaurantsRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.RandomUtil;
import com.ocom.common.utils.RequestUtil;
import com.ocom.common.utils.ResultUtil;
import com.ocom.security.authentication.YoCiUser;
import com.ocom.security.utils.SecurityUtils;
import com.ocom.webapi.feign.CompanyClientService;
import com.ocom.webapi.feign.MinioClientService;
import com.ocom.webapi.feign.PayConfigClientService;
import com.ocom.webapi.feign.XcxFeign;
import lombok.extern.log4j.Log4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.poi.util.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

@RestController
@PreAuthorize("@pms.hasRole('ROLE_WEB')" )
@Log4j
public class RestaurantController {

    @Autowired
    private PayConfigClientService payConfigClientService;
    @Autowired
    private XcxFeign xcxFeign;
    @Autowired
    private CompanyClientService companyClientService;
    @Autowired
    private MinioClientService minioClientService;

    @Value("${excel.dir}")
    String excelPath;


    @PostMapping(WebApiServiceUrl.Url_RestaurantOnShow)
    public Result RestaurantOnShow(@RequestBody RestaurantOnShowRequest request) {
        YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
        Long comId = yoCiUser.getComId();
        request.setComId(comId);

        String strPoints = "";
        if (null != request.getMerchId() && 0 < request.getMerchId()) {
            Result result = payConfigClientService.getPointsByMerch(comId, request.getMerchId());
            if (200 != result.getCode() && null != result.getData()) {
                JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(result.getData()));
                strPoints = jsonObject.getString("strPoints");
            }
        }
        if (null != request.getPointId() && -1 != request.getPointId()) {
            strPoints = String.valueOf(request.getPointId());
        }


        LoadRestaurantsRequest loadRestaurantsRequest = new LoadRestaurantsRequest();
        loadRestaurantsRequest.setComId(comId);
        loadRestaurantsRequest.setPointName(request.getPointName());
        loadRestaurantsRequest.setStrPoints(strPoints);

        return payConfigClientService.restaurantList(loadRestaurantsRequest);
    }

    @PostMapping(WebApiServiceUrl.Url_RestaurantAdd)
    public Result RestaurantAdd(@RequestBody RestaurantAddRequest request) {
        YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
        Long comId = yoCiUser.getComId();
        request.setComId(comId);
        return payConfigClientService.newRestaurant(request);
    }

    @PostMapping(WebApiServiceUrl.Url_RestaurantInfo)
    public Result RestaurantInfo(@RequestBody RestaurantInfoRequest request) {
        YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
        Long comId = yoCiUser.getComId();
        request.setComId(comId);
        return payConfigClientService.saveRestaurantInfo(request);
    }

    @PostMapping(WebApiServiceUrl.Url_RestaurantSetLogo)
    public Result RestaurantSetLogo(@RequestBody RestaurantSetLogoRequest request) {
        YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
        Long comId = yoCiUser.getComId();
        request.setComId(comId);
        return payConfigClientService.setRestaurantLogo(request);
    }

    @PostMapping(WebApiServiceUrl.Url_RestaurantAppId)
    public Result RestaurantAppId(@RequestBody RestaurantAppIdRequest request) throws IOException {
        YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
        Long comId = yoCiUser.getComId();
        request.setComId(comId);

        Result result = companyClientService.getAppInfoByName(request.getAppName());
        if (200 != result.getCode()) {
            return result;
        }

        EntityWechatAppInfo entityWechatAppInfo = JSON.parseObject(JSON.toJSONString(result.getData()), EntityWechatAppInfo.class);

        result = xcxFeign.getXcxAccessToken(comId, entityWechatAppInfo.getAppid(), entityWechatAppInfo.getAppsecret());
        if (200 != result.getCode()) {
            return result;
        }

        String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + String.valueOf(result.getData());
        log.info("获取小程序码url:" + url);

        JSONObject paramJson = new JSONObject();
        // 注意小程序页面如果不存在，则注释掉page参数
        //paramJson.put("page", "");
        paramJson.put("scene", "c=" + comId + "&p=" + request.getPointId());
        log.info("获取小程序码param:" + paramJson);

        String filePath = excelPath + comId + "_" + request.getAppName() + "_" + RandomUtil.generateNumber(5) + ".png";

        boolean getQRcode = getMiniqrQr(url, paramJson, filePath);
        if (!getQRcode) {
            return ResultUtil.error(ResultEnum.Err_4135);
        }
        File file = null;
        try {
            file = new File(filePath);

            Result uploadResult = minioClientService.upload(file);
            log.info("uploadResult:" + uploadResult);

            if (uploadResult.getCode() != 200) {
                return uploadResult;
            }
            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(uploadResult.getData()));
            log.info("uploadResultJsonObject:" + jsonObject);
            request.setImageUrl(jsonObject.getString("imageUrl"));
        } catch (Exception e) {
            e.printStackTrace();
            log.info("文件上传失败：" + e.getMessage());
        } finally {
            if (null != file && file.exists()) {
                //删除本地
                file.delete();
            }
        }

        log.info("restaurantQrCode：" + request);
        request.setAppid(entityWechatAppInfo.getAppid());
        return payConfigClientService.restaurantQrCode(request);
    }


    public boolean getMiniqrQr(String wxCodeURL, JSONObject paramJson, String filePath) {
        boolean result = false;
        try {
            URL url = new URL(wxCodeURL);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setRequestMethod("POST");
            // conn.setConnectTimeout(10000);
            // conn.setReadTimeout(2000);
            // 发送POST请求必须设置如下两行
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
            // 发送请求参数
            printWriter.write(paramJson.toString());
            // flush输出流的缓冲
            printWriter.flush();
            //开始获取数据

            try (BufferedInputStream bis = new BufferedInputStream(httpURLConnection.getInputStream());
                 OutputStream os = new FileOutputStream(new File(filePath));
            ) {

                BufferedImage read = ImageIO.read(httpURLConnection.getInputStream());
                if (read == null) {
                    log.info("没有该图片");
                } else {
                    ImageIO.write(read, "png", new File(filePath));
                    result = true;
                }
                int len;
                byte[] arr = new byte[1024];
                while ((len = bis.read(arr)) != -1) {
                    os.write(arr, 0, len);
                    os.flush();
                }
            }

        } catch (Exception e) {
            log.error("===> error : ", e);
        }

        return result;
    }


    @PostMapping(WebApiServiceUrl.Url_RestaurantDelete)
    public Result RestaurantDelete(@RequestBody RestaurantDeleteRequest request) {
        YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
        Long comId = yoCiUser.getComId();
        request.setComId(comId);
        return payConfigClientService.removeRestaurant(request);
    }

}
